package com.ajavaer.framework.office.excel.annotation;


import com.ajavaer.framework.common.tools.GenericsTools;
import com.ajavaer.framework.office.annotaion.Office;
import com.ajavaer.framework.office.excel.exception.ExcelAnnotationException;
import com.ajavaer.framework.office.excel.model.ExcelColumnModel;
import com.ajavaer.framework.office.excel.model.ExcelSheetModel;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author 李永曜
 * @说明: 读取指定类型中的注解
 */
public class ExcelAnnotaionReader {
    private Class<?> clazz;// 类
    private Office office;// Excel注解
    // <类,工作薄模型>
    private Map<Class<?>, ExcelSheetModel> sheetMap;// 工作簿名称
    // <类,列模型>
    private Map<Class<?>, ExcelColumnModel> columnMap;

    public ExcelAnnotaionReader(Class<?> clazz) {
        this.clazz = clazz;
        if (clazz.isAnnotationPresent(Office.class)) {
            office = (Office) clazz.getAnnotation(Office.class);
        } else {
            throw new ExcelAnnotationException("在" + clazz.getName()
                    + "中未找到Office注解");
        }

        columnMap = new HashMap<>();
        sheetMap = new HashMap<>();
        for (Field field : clazz.getDeclaredFields()) {
            Class<?> fileClass = GenericsTools.getFieldGenericType(field);// 成员变量泛型的真实类型
            ExcelSheetModel sm = sheetMap.get(fileClass);// 获得该类所属的工作簿模型
            if (sm == null) {
                sm = new ExcelSheetModel();
            }
            for (Annotation annotation : field.getAnnotations()) {
                if (annotation.annotationType() == ExcelSheet.class) {
                    int index = ((ExcelSheet) annotation).index();
                    Map<String, ExcelSheet> fileldsMap = sm.getSheetMap().get(
                            index);
                    if (fileldsMap == null) {
                        fileldsMap = new HashMap<>();
                    }
                    fileldsMap.put(field.getName(), (ExcelSheet) annotation);
                    sm.getSheetMap().put(index, fileldsMap);
                    sm.getSheetFields().put(index, field);
                }
            }
            sheetMap.put(fileClass, sm);
            ExcelColumnModel cm = columnMap.get(fileClass);// 获得该类所属的列模型
            if (cm == null) {
                cm = new ExcelColumnModel();
            }
            // 遍历成员变量
            for (Field f : fileClass.getDeclaredFields()) {
                for (Annotation annotation : f.getAnnotations()) {
                    if (annotation.annotationType() == ExcelColumn.class) {
                        int index = ((ExcelColumn) annotation).index();
                        Map<String, ExcelColumn> fileldsMap = cm.getModelMap()
                                .get(index);
                        if (fileldsMap == null) {
                            fileldsMap = new HashMap<>();
                        }
                        ExcelColumn column = (ExcelColumn) annotation;
                        fileldsMap.put(f.getName(), column);
                        cm.getModelMap().put(index, fileldsMap);
                    }
                }
            }
            columnMap.put(fileClass, cm);
        }
    }

    public Class<?> getClazz() {
        return clazz;
    }

    public void setClazz(Class<?> clazz) {
        this.clazz = clazz;
    }

    public Office getOffice() {
        return office;
    }

    public void setOffice(Office office) {
        this.office = office;
    }

    public Map<Class<?>, ExcelColumnModel> getColumnMap() {
        return columnMap;
    }

    public void setColumnMap(Map<Class<?>, ExcelColumnModel> columnMap) {
        this.columnMap = columnMap;
    }

    public Map<Class<?>, ExcelSheetModel> getSheetMap() {
        return sheetMap;
    }

    public void setSheetMap(Map<Class<?>, ExcelSheetModel> sheetMap) {
        this.sheetMap = sheetMap;
    }


}
